package com.aierkeji.b2c.utils;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;

import com.aierkeji.b2c.constants.Contants;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.UUID;


public class HttpUtils {

	private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

	/**
	 * 默认Get方法
	 *
	 * @throws IOException
	 */
	public static String defaultGetMethod(String url) {
		try(CloseableHttpClient client = HttpClients.createDefault()) {
			log.info("http invoke log start:method-get,url-" + url);
			HttpGet httpMethod = new HttpGet(url);
			HttpResponse response = client.execute(httpMethod);
			String resp = getResponseEntityString(response);
			log.info("http invoke log end:method-get,url-" + url + ",response-" + resp);
			return resp;
		} catch (Exception e) {
			log.error("Exception", e);
			return null;
		}
	}

	/** 请求响应格式均为json的Get方法 */
	public static String getMethodWithJsonHeader(String url) {
		try {
			return getMethodWithJsonHeader(url, null, null);
		} catch (Exception e) {
			log.error("Exception", e);
			return null;
		}
	}

	/**
	 * 请求响应格式均为json的Get方法
	 *
	 * @throws IOException
	 */
	public static String getMethodWithJsonHeader(String url, Map<String, String> paramsMap, Map<String, String> header)
			throws IOException {
		CloseableHttpClient client = null;
		String httpId = UUID.randomUUID().toString().replaceAll("-", "");
		try {
			log.info("http invoke log start:id-"+httpId+",method-get,url-" + url + ",params-" + GsonUtils.parseToJson(paramsMap)
					+ ",header-" + GsonUtils.parseToJson(header));
			url = url + "?";
			if (paramsMap != null) {
				for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
					url = url + entry.getKey() + "=" + entry.getValue() + "&";
				}
			}

			client = HttpClients.createDefault();
			HttpGet httpMethod = new HttpGet(url);
			httpMethod.setHeader(HTTP.CONTENT_TYPE, Contants.HTTP_CONTENT_TYPE_JSON);
			httpMethod.setHeader("Accept", Contants.HTTP_ACCEPT_JSON);

			if (header != null) {
				for (Map.Entry<String, String> entry : header.entrySet()) {
					httpMethod.setHeader(entry.getKey(), entry.getValue());
				}
			}
			HttpResponse response = client.execute(httpMethod);
			String resp = getResponseEntityString(response);
			log.info("http invoke log end:id-"+httpId+",method-get,url-" + url + ",response-" + resp);
			return resp;
		} catch (Exception e) {
			log.error("Exception with id:"+httpId, e);
			return null;
		} finally {
			if (client != null) {
				client.close();
			}
		}
	}

	/**
	 * 请求响应格式均为json的post方法
	 *
	 * @throws IOException
	 */
	public static String postMethodWithJsonHeader(String url, Map<String, Object> paramsMap, Map<String, String> header) {
		try {
			return postMethodWithJsonHeader(url, GsonUtils.parseToJson(paramsMap), header);
		} catch (Exception e) {
			log.error("Exception", e);
			return null;
		}
	}

	/** 请求响应格式均为json的post方法
	 * @throws IOException */
	public static String postMethodWithJsonHeader(String url, String body,Map<String,String> header) throws IOException {
		CloseableHttpClient client = null;
		String httpId = UUID.randomUUID().toString().replaceAll("-", "");
		try {
			log.info("http invoke log start:method-post,id-"+httpId+" url-"+url+",params-"+
					body+",header-"+header);

			client = HttpClients.createDefault();

			RequestConfig config = RequestConfig.custom()
					.setConnectTimeout(25000)
					.setConnectionRequestTimeout(25000).setSocketTimeout(25000).build();

			HttpPost httpMethod = new HttpPost(url);
			httpMethod.setConfig(config);
			httpMethod.setHeader(HTTP.CONTENT_TYPE, Contants.HTTP_CONTENT_TYPE_JSON);
			httpMethod.setHeader("Accept", Contants.HTTP_ACCEPT_JSON);
			if(header != null){
				for(Map.Entry<String, String> entry:header.entrySet()){
					httpMethod.setHeader(entry.getKey(), entry.getValue());
				}
			}
			StringEntity se = new StringEntity(body,Consts.UTF_8);// 转Json字符串
			se.setContentType("text/json");
			httpMethod.setEntity(se);
			HttpResponse response = client.execute(httpMethod);
			String resp = getResponseEntityString(response);
			log.info("http invoke log end:method-post,id-"+httpId+",url-"+url+",response-"+resp);
			return resp;
		} catch (Exception e) {
			log.error("http invoke Exception with id "+httpId, e);
			return null;
		}finally {
			if(client != null){
				client.close();
			}
		}
	}

	/** 请求响应格式均为json的post方法 */
	public static String postMethodWithJsonHeader(String url, Map<String, Object> paramsMap) {
		try {
			return postMethodWithJsonHeader(url, paramsMap, null);
		} catch (Exception e) {
			log.error("Exception", e);
			return null;
		}
	}

	/** 上传文件 */
	public static String postFile(String url, String name, File file) {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		try {
			// 把一个普通参数和文件上传给下面这个地址 是一个servlet
			HttpPost httpPost = new HttpPost(url);
			// 把文件转换成流对象FileBody
			FileBody bin = new FileBody(file);
			/*
			 * StringBody uploadFileName = new StringBody("my.png",
			 * ContentType.create("text/plain", Consts.UTF_8));
			 */
			// 以浏览器兼容模式运行，防止文件名乱码。
			HttpEntity reqEntity = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
					.addPart(name, bin).build(); // uploadFile对应服务端类的同名属性<File类型>
			// .addPart("uploadFileName", uploadFileName)//
			// uploadFileName对应服务端类的同名属性<String类型>

			httpPost.setEntity(reqEntity);

			log.info("post file to: " + httpPost.getRequestLine());
			// 发起请求 并返回请求的响应
			CloseableHttpResponse response = httpClient.execute(httpPost);
			String resp = getResponseEntityString(response);
			log.info("post file to: " + httpPost.getRequestLine() + " end with response:" + resp);
			return resp;
		} catch (Exception e) {
			log.error("Exception", e);
			return null;
		} finally {
			try {
				httpClient.close();
			} catch (IOException e) {
				log.error("Exception", e);
				return null;
			}
		}
	}

	public static String getResponseEntityString(HttpResponse response) {
		try {
			if (response.getStatusLine().getStatusCode() == HttpStatus.OK.value()) {
				String resp = "";
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					resp = EntityUtils.toString(resEntity, Consts.UTF_8);
					return resp;
				} else {
					log.info("resEntity is null.......");
				}
			} else {
				log.error("response status is " + response.getStatusLine().getStatusCode());
				String resp = "";
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					resp = EntityUtils.toString(resEntity, Consts.UTF_8);
					return resp;
				} else {
					log.info("resEntity is null.......");
				}
			}
			return null;
		} catch (Exception e) {
			log.error("Exception", e);
			return null;
		}
	}

	public static void main(String[] args) throws ClientProtocolException, IOException {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		try {
			// 要上传的文件的路径
			String filePath = new String("C:/Users/James/Desktop/temp-code/123.csv");
			// 把一个普通参数和文件上传给下面这个地址 是一个servlet
			HttpPost httpPost = new HttpPost("http://172.16.6.9:8081/wxInterface/mservice/Rdl/FileUpload2.do");
			// 把文件转换成流对象FileBody
			File file = new File(filePath);
			FileBody bin = new FileBody(file);
			/*
			 * StringBody uploadFileName = new StringBody("my.png",
			 * ContentType.create("text/plain", Consts.UTF_8));
			 */
			// 以浏览器兼容模式运行，防止文件名乱码。
			HttpEntity reqEntity = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
					.addPart("rdl", bin).build(); // uploadFile对应服务端类的同名属性<File类型>
			// .addPart("uploadFileName", uploadFileName)//
			// uploadFileName对应服务端类的同名属性<String类型>

			httpPost.setEntity(reqEntity);

			System.out.println("发起请求的页面地址 " + httpPost.getRequestLine());
			// 发起请求 并返回请求的响应
			CloseableHttpResponse response = httpClient.execute(httpPost);
			try {
				// 打印响应状态
				System.out.println(response.getStatusLine());
				// 获取响应对象
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					// 打印响应长度
					System.out.println("Response content length: " + resEntity.getContentLength());
					// 打印响应内容
					System.out.println(EntityUtils.toString(resEntity, Charset.forName("UTF-8")));
				}
				// 销毁
				EntityUtils.consume(resEntity);
			} finally {
				response.close();
			}
		} finally {
			httpClient.close();
		}
	}

}
